package com.fuyao.cloud.personnel.library.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fuyao.cloud.common.biz.service.FyBaseServiceImpl;
import com.fuyao.cloud.personnel.library.entity.BookCategory;
import com.fuyao.cloud.personnel.library.mapper.BookCategoryMapper;
import com.fuyao.cloud.personnel.library.service.BookCategoryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class BookCategoryServiceImpl extends FyBaseServiceImpl<BookCategoryMapper, BookCategory> implements BookCategoryService {
    @Override
    public BookCategory findByFullCode(String fullCode) {
        return baseMapper.selectOne(Wrappers.<BookCategory>lambdaQuery().eq(BookCategory::getFullName, fullCode));
    }

    @Override
    public List<Tree<Long>> selectTree() {
        List<BookCategory> bookCategories = baseMapper.selectList(null);

        List<TreeNode<Long>> collect = bookCategories.stream().map(bookCategory -> {
            TreeNode<Long> treeNode = new TreeNode<>();
            treeNode.setId(bookCategory.getId());
            treeNode.setParentId(bookCategory.getParentId() == null ? -1L : bookCategory.getParentId());
            treeNode.setName(bookCategory.getName());
            treeNode.setWeight(bookCategory.getCreateTime());
            Map<String, Object> extra = new HashMap<>(1);
            extra.put("fullName", bookCategory.getFullName());
            treeNode.setExtra(extra);
            return treeNode;
        }).collect(Collectors.toList());

        return TreeUtil.build(collect, -1L);
    }

    @Transactional
    @Override
    public BookCategory saveCategory(BookCategory bookCategory) {
        String newFullName = bookCategory.getName();
        if (bookCategory.getParentId() != null) {
            BookCategory parent = baseMapper.selectById(bookCategory.getParentId());
            if (parent != null) {
                newFullName = parent.getFullName() + "/" + bookCategory.getName();
            }
        }
        bookCategory.setFullName(newFullName);
        save(bookCategory);

        return bookCategory;
    }

    @Transactional
    @Override
    public BookCategory updateCategory(BookCategory category) {
        BookCategory bookCategory = getById(category.getId());

        String oldFullName = bookCategory.getFullName();

        BookCategory parent = baseMapper.selectById(category.getParentId());

        String newFullName = category.getName();

        if (parent != null) {
            newFullName = parent.getFullName() + "/" + category.getName();
        }

        category.setFullName(newFullName);

        if (!Objects.equals(oldFullName, newFullName)) {
            List<BookCategory> bookCategories = baseMapper.selectList(Wrappers.<BookCategory>lambdaQuery().likeRight(BookCategory::getFullName, oldFullName));

            Pattern pattern = Pattern.compile("^" + Pattern.quote(oldFullName));
            for (BookCategory bookCategory1 : bookCategories) {
                Matcher matcher = pattern.matcher(bookCategory1.getFullName());
                if (matcher.find()) {
                    bookCategory1.setFullName(matcher.replaceFirst(newFullName));
                }
            }
            updateBatchById(bookCategories);
        }

        updateById(category);

        return category;
    }
}
